/*
 * 3x3 matrix
 */
#ifndef _JPMAT3_H_
#define _JPMAT3_H_

#include "JPVec3.h"

class JPMat3
{
	float m[3][3];

	JPMat3() {}
	JPMat3 (float a00, float a01, float a02,
			float a10, float a11, float a12,
			float a20, float a21, float a22)
	{ 
		m[0][0] = a00; m[0][1] = a01; m[0][2] = a02;
		m[1][0] = a10; m[1][1] = a11; m[1][2] = a12;
		m[2][0] = a20; m[2][1] = a21; m[2][2] = a22;
	}

	//----------------------------------------
	// operator overloads
	//----------------------------------------

	JPMat3 operator *(float n) const
	{
		return JPMat3(	m[0][0] * n, m[0][1] * n, m[0][2] * n,
						m[1][0] * n, m[1][1] * n, m[1][2] * n,
						m[2][0] * n, m[2][1] * n, m[2][2] * n);
	}

	JPMat3 operator /(float n) const
	{
		return JPMat3(	m[0][0] / n, m[0][1] / n, m[0][2] / n,
						m[1][0] / n, m[1][1] / n, m[1][2] / n,
						m[2][0] / n, m[2][1] / n, m[2][2] / n);
	}

	JPVec3 operator *(const JPVec3 &v) const
	{
		return JPVec3(	m[0][0]* v.x + m[0][1]* v.y + m[0][2]* v.z,
						m[1][0]* v.x + m[1][1]* v.y + m[1][2]* v.z,
						m[2][0]* v.x + m[2][1]* v.y + m[2][2]* v.z);
	}

	JPMat3 operator *(const JPMat3 &mat) const
	{
		return JPMat3(	m[0][0]*mat.m[0][0] + m[0][1]*mat.m[1][0] + m[0][2]*mat.m[2][0],
						m[0][0]*mat.m[0][1] + m[0][1]*mat.m[1][1] + m[0][2]*mat.m[2][1],
						m[0][0]*mat.m[0][2] + m[0][1]*mat.m[1][2] + m[0][2]*mat.m[2][2],

						m[1][0]*mat.m[0][0] + m[1][1]*mat.m[1][0] + m[1][2]*mat.m[2][0],
						m[1][0]*mat.m[0][1] + m[1][1]*mat.m[1][1] + m[1][2]*mat.m[2][1],
						m[1][0]*mat.m[0][2] + m[1][1]*mat.m[1][2] + m[1][2]*mat.m[2][2],

						m[2][0]*mat.m[0][0] + m[2][1]*mat.m[1][0] + m[2][2]*mat.m[2][0],
						m[2][0]*mat.m[0][1] + m[2][1]*mat.m[1][1] + m[2][2]*mat.m[2][1],
						m[2][0]*mat.m[0][2] + m[2][1]*mat.m[1][2] + m[2][2]*mat.m[2][2]);
	}

	JPVec3 column (int column) const { return JPVec3(m[0][column], m[1][column], m[2][column]); }
	JPVec3 row    (int row)    const { return JPVec3(m[row][0], m[row][1], m[row][2]); }
};

#endif // JPMAT3_H_